package config

import dao._
import com.db4o.{ObjectContainer, Db4oEmbedded}
import com.db4o.config.{EmbeddedConfiguration}
import com.db4o.reflect.jdk.{JdkReflector}
/** Singleton encargado de mantener contantes y servicios disponibles para toda la aplicación de forma homogénea.
 */
object Services {
  val uploadFolder ="/public/uploads/"
  val appPath = play.Play.applicationPath
  val avatarsPath = uploadFolder + "avatars/full/"
  val avatarsThumbPath = uploadFolder + "avatars/thumb/"
  val resizedImagesPath = uploadFolder + "images/"
  val imagesPath = uploadFolder + "images/full/"
  val videosPath = uploadFolder + "videos/"
  val soundsPath = uploadFolder + "videos/"
  
  val defaultAvatarWidth = 250
  val defaultThumbWidth = 75
  val defaultImageWidth = 400
  
  // nombre del archivo donde crear la BD
  private val DB4ODBNAME = "selmasongs.db4o"
  private val conf:EmbeddedConfiguration = Db4oEmbedded.newConfiguration()
  
  //Aunar los classloaders de Play! y Db4o
  conf.common().reflectWith(
      new JdkReflector(Thread.currentThread().getContextClassLoader())
      )
  //configurar los índices
  conf.common().objectClass(models.User).objectField("name").indexed(true)
  
  conf.file().lockDatabaseFile(true)
  
  //DI simple
  val dbServer:ObjectContainer = { play.Logger.info("Opening database..."); Db4oEmbedded.openFile(conf, DB4ODBNAME) }
  implicit lazy val dbSession = new Session(dbServer)
  
  /**
   * Permite el manejo automático de objetos que necesiten conectarse/desconectarse. Provee el DLS
   * {{{
   * using(objeto){ o =>
   *    sentencias
   * }
   * }}}
   * @param resource objeto de cualquier tipo (T) que implemente los métodos connect() y disconnect()
   * @param block función del tipo (T) => U
   * @return U valor devuelto por block
   */
  def using[T <: { def connect(); def disconnect() }, U](resource: T)(block: T => U):U = {
    try {
      resource.connect()
      block(resource)
    } finally {
      if (resource != null) resource.disconnect()
    }
  }
  
  def concretePath(relPath:String) = appPath + relPath
  
}
